import * as echarts from "echarts";
import type { ECharts, EChartsOption, ToolboxComponentOption } from "echarts";
import { debounce } from 'lodash-es';


/**
 * 初始化图表
 * @param id 图表ID
 * @param option 图表配置
 * @param title 标题
 * @param subtext 副标题
 */
const initChart = (id: string, option: EChartsOption, title?: string, subtext?: string) => {
    if (title || subtext) {
        option.title = {
            text: title,
            subtext: subtext,
        };
    }

    const chartDom = document.getElementById(id);
    if (!chartDom) {
        return null;
    }

    const chartInstance = echarts.init(chartDom);
    chartInstance.setOption(option);
    //响应式调整大小
    resizeChart(chartInstance, document.getElementById(id)!);
    return chartInstance;
};

// 存储 resize 回调函数引用
const resizeCallbacks = new WeakMap<ECharts, () => void>();

/**
 * 响应式调整图表大小
 * @param chartInstance
 */
const resizeChart = (chartInstance: ECharts, chartDom: HTMLElement) => {
    const resizeHandler = debounce(() => {
        if (!chartInstance.isDisposed()) {
            chartInstance.resize();
        }
    }, 200);

    const resizeObserver = new ResizeObserver(resizeHandler);
    resizeObserver.observe(chartDom);

    // 同时保留窗口resize监听
    window.addEventListener("resize", resizeHandler);

    resizeCallbacks.set(chartInstance, () => {
        resizeObserver.disconnect();
        window.removeEventListener("resize", resizeHandler);
    });
};

/**
 * 销毁图表实例
 * @param chartInstance
 * @returns
 */
const disposeChart = (chartInstance: ECharts) => {
    // console.log("销毁图表实例");
    // const cleanup = resizeCallbacks.get(chartInstance);
    // if (cleanup) {
    //     cleanup();
    //     resizeCallbacks.delete(chartInstance);
    //     chartInstance.dispose();
    // }
    if (chartInstance && !chartInstance.isDisposed()) {
        chartInstance.clear();
        chartInstance.dispose();
    }
};

//工具栏
const toolbox: ToolboxComponentOption = {
    feature: {
        dataView: {
            show: true,
            readOnly: false,
            title: '数据视图',
            lang: ['数据视图', '关闭', '刷新']
        },
        magicType: {
            show: true,
            type: ['line', 'bar'],
            title: {
                line: '切换为折线图',
                bar: '切换为柱状图',
                stack: '切换为堆叠',
                tiled: '切换为平铺',
            }
        },
        restore: { show: true, title: '还原' },
        saveAsImage: { show: true, title: '保存为图片' }
    }
}

/**
 * 柱状图
 */
const Bar = {
    basic({ id, xData, yData, title, subtext }: ChartOptions) {
        const option: EChartsOption = {
            xAxis: {
                type: "category",
                data: xData,
            },
            yAxis: {
                type: "value",
            },
            series: [
                {
                    data: yData,
                    type: "bar",
                },
            ],
        };
        return initChart(id, option, title, subtext);
    },
    pup({ id, yData, data, title, subtext }: ChartOptions) {
        const option: EChartsOption = {
            tooltip: {
                trigger: "axis",
                axisPointer: { type: "shadow" },
            },
            legend: {},
            grid: {
                left: "1%",
                right: "5%",
                bottom: "2%",
                top: "15%",
                containLabel: true,
            },
            xAxis: {
                type: "value",
                boundaryGap: [0, 0.01],
            },
            yAxis: {
                type: "category",
                data: yData,
            },
            series: [
                {
                    type: "bar",
                    data: data,
                },
            ],
        };
        return initChart(id, option, title, subtext);
    },
    statistics({ id, data, score, total, average, passed, title, subtext }: StatisticsOptions) {
        const option: EChartsOption = {
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'cross',
                    crossStyle: {
                        color: 'rgba(118, 117, 117, 0.5)'
                    }
                },
                formatter: (params: any) => {
                    const title = '<span style="font-weight: bold;">' + params[0].name + '</span><br>';
                    const first = params[0].seriesName + ': ' + params[0].value + ' 分<br>';
                    const second = params[1].seriesName + ': ' + total[params[0].dataIndex] + ' 分<br>';
                    const third = params[2].seriesName + ': ' + params[2].value + ' 分<br>';
                    const fourth = '结果: ' + (passed[params[0].dataIndex] ? '<span style="color:green;">及格</span>' : '<span style="color:red;">不及格</span>') + '<br>';
                    return title + first + second + third + fourth;
                }
            },
            grid: {
                left: "1%",
                right: "1%",
                bottom: "1%",
                top: "15%",
                containLabel: true,
            },
            toolbox: toolbox,
            legend: {
                data: ['得分', '总分', '平均分']
            },
            xAxis: [
                {
                    type: 'category',
                    data: data,
                    axisPointer: {
                        type: 'shadow'
                    }
                }
            ],
            yAxis: { type: 'value' },
            series: [
                {
                    name: '得分',
                    type: 'bar',
                    stack: 'total',
                    showBackground: true,
                    label: {
                        show: true,
                        position: 'top',
                        fontSize: 14,
                        color: 'rgba(4, 87, 253, 0.5)',
                        formatter: (params: any) => params.value
                    },
                    itemStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                            { offset: 0, color: 'rgba(74, 0, 245, 0.5)' },
                            { offset: 0.5, color: 'rgba(0, 4, 253, 0.5)' },
                            { offset: 1, color: 'rgba(186, 0, 253, 0.5)' }
                        ])
                    },
                    emphasis: {
                        itemStyle: {
                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                { offset: 0, color: 'rgba(74, 0, 245, 0.5)' },
                                { offset: 0.5, color: 'rgba(0, 4, 253, 0.5)' },
                                { offset: 1, color: 'rgba(186, 0, 253, 0.5)' }])
                        }
                    },
                    data: score
                },
                {
                    name: '总分',
                    type: 'bar',
                    stack: 'total',
                    itemStyle: {
                        color: 'rgba(15, 3, 38, 0.2)'
                    },
                    data: total.map((item, index) => item - score[index])
                },
                {
                    name: '平均分',
                    type: 'line',
                    itemStyle: {
                        color: 'rgba(0, 255, 68, 0.5)'
                    },
                    smooth: true,
                    data: average
                }
            ]
        };
        return initChart(id, option, title, subtext);
    },
    userScore: ({ id, xData, yData, title, subtext }: ChartOptions) => {
        const option: EChartsOption = {
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'cross',
                    crossStyle: {
                        color: '#999'
                    }
                }
            },
            legend: {
                data: ['分数']
            },
            grid: {
                left: "1%",
                right: "1%",
                bottom: "1%",
                top: "15%",
                containLabel: true,
            },
            toolbox: toolbox,
            calculable: true,
            xAxis: {
                type: "category",
                data: xData,
            },
            yAxis: {
                type: "value",
            },
            series: [
                {
                    name: '分数',
                    type: 'bar',
                    data: yData,
                    markPoint: {
                        data: [
                            { type: 'max', name: 'Max' },
                            { type: 'min', name: 'Min' }
                        ]
                    },
                    markLine: {
                        data: [{ type: 'average', name: 'Avg' }]
                    }
                },
            ],
        };
        return initChart(id, option, title, subtext);
    },
};

/**
 * 折线图
 */
const Line = {
    basic({ id, xData, yData, title, subtext }: ChartOptions) {
        const option: EChartsOption = {
            legend: {},
            grid: {
                left: "1%",
                right: "5%",
                bottom: "2%",
                top: "20%",
                containLabel: true,
            },
            xAxis: {
                type: "category",
                data: xData,
            },
            yAxis: {
                type: "value",
            },
            series: [
                {
                    data: yData,
                    type: "line",
                    smooth: true,
                },
            ],
        };
        return initChart(id, option, title, subtext);
    },
};

/**
 * 饼图
 */
const Pie = {
    basic({ id, value, title, subtext }: ChartOptions) {
        const option: EChartsOption = {
            legend: {},
            series: [
                {
                    type: "gauge",
                    startAngle: 90,
                    endAngle: -270,
                    pointer: { show: false },
                    progress: {
                        show: true,
                        overlap: false,
                        roundCap: true,
                        clip: false,
                        itemStyle: {
                            borderWidth: 1,
                            borderColor: "#464646",
                        },
                    },
                    axisLine: { lineStyle: { width: 20 } },
                    splitLine: { show: false, distance: 0, length: 10 },
                    axisTick: { show: false },
                    axisLabel: { show: false, distance: 50 },
                    data: [
                        {
                            value: value,
                            title: { offsetCenter: ["0%", "10%"] },
                            detail: {
                                valueAnimation: true,
                                offsetCenter: ["0%", "10%"],
                            },
                        },
                    ],
                    title: { fontSize: 14 },
                    detail: {
                        width: 50,
                        height: 14,
                        fontSize: 14,
                        color: "inherit",
                        borderColor: "inherit",
                        borderRadius: 10,
                        borderWidth: 1,
                        formatter: "{value}%",
                    },
                },
            ],
        };
        return initChart(id, option, title, subtext);
    },
    segmentation(id: string, value: any[], title?: string, subtext?: string) {
        const option: EChartsOption = {
            legend: {
                top: 'bottom',
            },
            tooltip: {
                trigger: 'item'
            },
            toolbox: {
                show: true,
                feature: {
                    mark: { show: true },
                    dataView: {
                        show: true,
                        readOnly: false,
                        title: '数据视图',
                        lang: ['数据视图', '关闭', '刷新']
                    },
                    restore: { show: true, title: '还原' },
                    saveAsImage: { show: true, title: '保存为图片' }
                }
            },
            series: [
                {
                    name: '分数段人数',
                    type: 'pie',
                    radius: [60, 120],
                    center: ['50%', '50%'],
                    padAngle: 2,
                    itemStyle: {
                        borderRadius: 7
                    },
                    data: value,
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    }
                }
            ]
        };
        return initChart(id, option, title, subtext);
    },
    passRate(id: string, value: number, title?: string, subtext?: string) {
        const option: EChartsOption = {
            series: [
                {
                    type: 'gauge',
                    progress: {
                        show: true,
                        width: 18
                    },
                    axisLine: {
                        lineStyle: {
                            width: 18
                        }
                    },
                    axisTick: {
                        show: false
                    },
                    splitLine: {
                        length: 2,
                        lineStyle: {
                            width: 1,
                            color: '#999'
                        }
                    },
                    axisLabel: {
                        distance: 20,
                        color: '#999',
                        fontSize: 15
                    },
                    anchor: {
                        show: true,
                        showAbove: true,
                        size: 15,
                        itemStyle: {
                            borderWidth: 10
                        }
                    },
                    detail: {
                        valueAnimation: true,
                        fontSize: 40,
                        formatter: '{value}%',
                        color: 'inherit',
                        offsetCenter: [0, '70%']
                    },
                    data: [
                        {
                            value: value
                        }
                    ]
                }
            ]
        }
        return initChart(id, option, title, subtext);
    }
};

/**
 * 暴露
 */
export {
    type ECharts,
    Bar, //柱状图
    Line, //折线图
    Pie, //饼图
    resizeChart, //窗口大小自适应
    disposeChart, //销毁图表
    initChart
};
